
import UIKit
import AddressBookUI

@objc
protocol PeoplesPickerNavigationControllerDelegate: NSObjectProtocol {
    optional func peoplesNavigationController(peoplesNavigationController: PeoplesPickerNavigationController, selectedContacts: [Contact])
}

private let statusBarHeight: CGFloat = 64
private let kHeightTableViewCell: CGFloat = 50
private let kBarButtonItemLeftMargin: CGFloat = 20
private let kCheckBoxBackgroundColor = UIColor(red: 0.2561, green: 0.6658, blue: 0.673, alpha: 1.0)
private let kSectionIndexColor = kBlueColor
private let alphabet = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L","M", "N",
                        "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "#"];
private let contactCellID = "contact"
private let kConstacts = "constacts"
private let kContactSortingLetter = "sortingLetter"
private let kTitle = "Select Contacts"

class PeoplesPickerNavigationController: UINavigationController {
    
    weak var peoplesDelegate: PeoplesPickerNavigationControllerDelegate?
    var checkBoxBackgroundColor = kCheckBoxBackgroundColor
    var sectionIndexColor = kSectionIndexColor

    private var allContacts: [Contact] = []
    private var selectedContacts: [Contact] = []
    private var contactsByLetter: [[String: AnyObject]] = []

    var rightBarButtonItem: UIButton = {
        let rightBarButtonItem = UIButton()
        rightBarButtonItem.setTitle(kDone, forState: .Normal)
        rightBarButtonItem.setTitleColor(kBlueColor, forState: .Normal)
        
        return rightBarButtonItem
    }()

    var leftBarButtonItem: UIButton = {
        let leftBarButtonItem = UIButton()
        leftBarButtonItem.setTitle(kCancel, forState: .Normal)
        leftBarButtonItem.setTitleColor(kBlueColor, forState: .Normal)
        
        return leftBarButtonItem
    }()

    var titleView: UIView = {
        let titleLabel = UILabel()
        titleLabel.text = ""
        return titleLabel
    }()
  
    private lazy var tableView: UITableView = {
        let tableView = UITableView(frame: CGRectZero, style: .Plain)
        tableView.delegate = self
        tableView.dataSource = self
        tableView.rowHeight = kHeightTableViewCell
        tableView.separatorStyle = .None
        tableView.contentInset = UIEdgeInsets(top: statusBarHeight, left: 0, bottom: 0, right: 0)
        tableView.contentOffset.y = -statusBarHeight
        return tableView
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        title = kTitle
        view.backgroundColor = UIColor.whiteColor()
        automaticallyAdjustsScrollViewInsets = false
        
        weak var weakSelf = self
        AddressBookKitHelp.allContactsHelp({ (contactArray, error) in
            if error != nil {
                let appName = NSBundle.mainBundle().infoDictionary?["CFBundleName"] as? String ?? ""
                let kUnauthorizedMessage = "授权失败, 请在设备的\"设置-隐私-照片\"选项中，允许 \(appName) 访问你的手机相册"
                
                let messageAlertView = UIAlertView(title: error?.domain, message: kUnauthorizedMessage, delegate: nil, cancelButtonTitle: "OK")
                messageAlertView.delegate = self
                messageAlertView.show()
                return
            }
            
            weakSelf?.allContacts = contactArray
            self.contactsGroupByLetter()
            weakSelf?.tableView.reloadData()
        })

        setBarButtonItem()
        navigationBar.addSubview(leftBarButtonItem)
        navigationBar.addSubview(titleView)
        navigationBar.addSubview(rightBarButtonItem)

        view.insertSubview(tableView, belowSubview: navigationBar)
        setTableView()
    }
    
    private func contactsGroupByLetter() {
        for letter in alphabet {
            var predicate = NSPredicate(format: "lastName BEGINSWITH[c] '\(letter)'")
            if letter == "#" {
                predicate = NSPredicate(format: "lastName = nil || lastName.length = 0 || lastName MATCHES %@", "[^a-zA-Z].*")
            }
            
            let array = allContacts as NSArray
            let names = array.filteredArrayUsingPredicate(predicate) as? [Contact]
            if names?.count > 0 {
                let contactByLetter: [String: AnyObject] = [kContactSortingLetter: letter, kConstacts: names!]
                contactsByLetter.append(contactByLetter)
            }
        }
    }
    
    private func setBarButtonItem()  {
        leftBarButtonItem.sizeToFit()
        leftBarButtonItem.frame.origin.x = kBarButtonItemLeftMargin
        leftBarButtonItem.addTarget(self, action: #selector(PeoplesPickerNavigationController.didTapCancel), forControlEvents: .TouchUpInside)
        
        rightBarButtonItem.sizeToFit()
        rightBarButtonItem.frame.origin.x = CGRectGetMaxX(UIScreen.mainScreen().bounds) - rightBarButtonItem.frame.size.width - kBarButtonItemLeftMargin
        rightBarButtonItem.addTarget(self, action: #selector(PeoplesPickerNavigationController.didTapDone), forControlEvents: .TouchUpInside)
        
        titleView.sizeToFit()
        titleView.center.x = navigationBar.center.x
    }

    private func setTableView() {
        let nib = UINib(nibName: "ContactCell", bundle: nil)
        tableView.registerNib(nib, forCellReuseIdentifier: contactCellID)
        tableView.sectionIndexColor = sectionIndexColor
        tableView.frame = UIScreen.mainScreen().bounds
    }
    
    func didTapCancel() {
        dismissViewControllerAnimated(true, completion: nil)
    }

    func didTapDone() {
        if selectedContacts.count > 0 {
            peoplesDelegate?.peoplesNavigationController?(self, selectedContacts: selectedContacts)
            return
        }

        didTapCancel()
    }
    
    deinit {
        print("deinit")
    }
}

extension PeoplesPickerNavigationController: UIAlertViewDelegate {
    func alertView(alertView: UIAlertView, clickedButtonAtIndex buttonIndex: Int) {
        dismissViewControllerAnimated(true, completion: nil)
    }
}

extension PeoplesPickerNavigationController: UITableViewDataSource {
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return contactsByLetter.count
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
        let contactsLetter = contactsByLetter[section][kConstacts] as! [Contact]
        return contactsLetter.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier(contactCellID) as! ContactCell
        let contactsLetterGroup = contactsByLetter[indexPath.section][kConstacts] as! [Contact]
        let contact = contactsLetterGroup[indexPath.row]
        
        cell.checkBoxBackgroundColor = checkBoxBackgroundColor
        cell.contact = contact
        cell.delegate = self
        
        return cell
    }
}

extension PeoplesPickerNavigationController: UITableViewDelegate {
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let contactsLetterGroup = contactsByLetter[indexPath.section][kConstacts] as! [Contact]
        let contact = contactsLetterGroup[indexPath.row]
        
        if contact.contactEmails.count == 0 {
            return
        }
        
        contact.isSelected = !contact.isSelected
        if contact.isSelected {
            selectedContacts.append(contact)
        } else {
            let index = selectedContacts.indexOf(contact)
            selectedContacts.removeAtIndex(index!)
        }
        
        tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
    }
    
    func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return contactsByLetter[section][kContactSortingLetter] as? String
    }
    
    func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 28.0
    }
    
    func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        return nil
    }
    
    func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 0.01
    }
    
    func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? {
        let contactsLetter = contactsByLetter as NSArray
        let lettersSorted = contactsLetter.valueForKey(kContactSortingLetter)
        
        return lettersSorted as? [String]
    }
}

extension PeoplesPickerNavigationController: ContactCellDelegate {
    func contactCellEditorEmail(contactCell: ContactCell, newContact: Contact) {
        
        var error:Unmanaged<CFErrorRef>?
        AddressBookKitHelp.saveAddressBookEmail(newContact, &error)
        if error != nil {
            UIAlertView(title: "error", message: "email update failed", delegate: nil, cancelButtonTitle: "ok").show()
            return
        }
        tableView.reloadData()
    }
}